{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.卷积层的平移不变性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "平移不变性：无论原图某个部分位置如何变化，经过卷积运算之后得到的对应特征部分的位置也会跟着变化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "例如：下图中原图中的输入一个在左下角一个在左上角，卷积运算后对应的结果也相应的位于左上角和左下角\n",
    "\n",
    "![v2-f73b8468c2004554063a38c849c6a116_720w](https://zyc-learning-1309954661.cos.ap-nanjing.myqcloud.com/machine-learning-pic/v2-f73b8468c2004554063a38c849c6a116_720w.webp)\n",
    "\n",
    "![v2-f73b8468c2004554063a38c849c6a116_720w](https://zyc-learning-1309954661.cos.ap-nanjing.myqcloud.com/machine-learning-pic/v2-f73b8468c2004554063a38c849c6a116_720w.webp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.验证卷积神经网络的有效性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "已知算子`[1, -1]`能够检测竖向的边缘"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "# 定义卷积运算\n",
    "def conv2d(x, mask):\n",
    "    if mask.ndim == 1:\n",
    "        mask = torch.reshape(mask,shape=(1, mask.size().numel()))\n",
    "\n",
    "    shape_out = ((x.shape[0] - mask.shape[0] + 1), (x.shape[1] - mask.shape[1] + 1))\n",
    "    out = torch.zeros(size=shape_out)\n",
    "    for i in range(shape_out[0]):\n",
    "        for j in range(shape_out[1]):\n",
    "            out[i,j] = (x[i:i+mask.shape[0], j:j+mask.shape[1]] * mask).sum()\n",
    "\n",
    "    return out\n",
    "\n",
    "x = torch.tensor(\n",
    "    [\n",
    "        [1,1,1,0,0,0,1,1],\n",
    "        [1,1,1,0,0,0,1,1],\n",
    "        [1,1,1,0,0,0,1,1],\n",
    "        [1,1,1,0,0,0,1,1],\n",
    "        [1,1,1,0,0,0,1,1]\n",
    "    ]\n",
    ")\n",
    "\n",
    "mask = torch.tensor([1, -1])\n",
    "\n",
    "conv2d(x, mask)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在，假如我们不知道算子（卷积核）长什么样，要通过学习学出来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([1, 1, 5, 8])\n",
      "torch.Size([1, 1, 5, 7])\n",
      "epoch:1, loss:25.147043228149414, weight:tensor([[[[0.8366, 0.2028]]]])\n",
      "epoch:2, loss:23.57193374633789, weight:tensor([[[[-0.0498, -1.0935]]]])\n",
      "epoch:3, loss:25.1626033782959, weight:tensor([[[[ 1.2941, -0.0365]]]])\n",
      "epoch:4, loss:28.80063819885254, weight:tensor([[[[ 0.0740, -1.4574]]]])\n",
      "epoch:5, loss:34.04216384887695, weight:tensor([[[[ 1.5969, -0.0751]]]])\n",
      "epoch:6, loss:40.79579544067383, weight:tensor([[[[ 0.0482, -1.7222]]]])\n",
      "epoch:7, loss:49.16925811767578, weight:tensor([[[[1.8403e+00, 1.0406e-03]]]])\n",
      "epoch:8, loss:59.39990997314453, weight:tensor([[[[-0.0690, -1.9565]]]])\n",
      "epoch:9, loss:71.82740783691406, weight:tensor([[[[2.0746, 0.1534]]]])\n",
      "epoch:10, loss:86.88836669921875, weight:tensor([[[[-0.2530, -2.1979]]]])\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "\n",
    "# 定义一层卷积网络\n",
    "net = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(1, 2), bias=False)\n",
    "\n",
    "# 定义数据和标签\n",
    "x = torch.tensor(\n",
    "    [\n",
    "        [1. ,1. ,1. ,0. ,0. ,0. ,1. ,1.],\n",
    "        [1. ,1. ,1. ,0. ,0. ,0. ,1. ,1.],\n",
    "        [1. ,1. ,1. ,0. ,0. ,0. ,1. ,1.],\n",
    "        [1. ,1. ,1. ,0. ,0. ,0. ,1. ,1.],\n",
    "        [1. ,1. ,1. ,0. ,0. ,0. ,1. ,1.],\n",
    "    ]\n",
    ")\n",
    "x = x.reshape(1,1,x.shape[0],x.shape[1])\n",
    "print(x.shape)\n",
    "\n",
    "y = torch.tensor(\n",
    "    [\n",
    "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
    "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
    "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
    "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.],\n",
    "        [ 0.,  0.,  1.,  0.,  0., -1.,  0.]\n",
    "    ]\n",
    ")\n",
    "y = y.reshape(1,1,y.shape[0],y.shape[1])\n",
    "print(y.shape)\n",
    "\n",
    "# 开始训练\n",
    "for i in range(10):\n",
    "    out = net(x)\n",
    "    loss = (out-y)**2\n",
    "    net.zero_grad()\n",
    "    loss.sum().backward()\n",
    "    net.weight.data -= 3e-2*net.weight.grad\n",
    "    print(f'epoch:{i+1}, loss:{loss.sum()}, weight:{net.weight.data}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后一组值`[ 0.9553, -0.9916]`与`[1, -1]`非常接近"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 实验一：直观理解卷积的作用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "原图如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x1d311c9c3a0>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAGdCAYAAAAv9mXmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAATzElEQVR4nO3db2hdhfnA8ee2palocrVaq1nTqtu0aEnHtA3BuTHtlCKivpJSWOf6ZiMVSxG2vln1VQqD4ZillDnsm5W6CVUQ1HXdmiKzWFsKVZhY6TCj/3Swe9PArpKc34sfZCs22pv2ucfkfj5wwBzPyXmO3N6v55zctFIURREAcJnNKnsAAGYmgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUc1p9wPHx8Th58mR0dnZGpVJp9eEBuARFUcTIyEh0d3fHrFlffI3S8sCcPHkyenp6Wn1YAC6j4eHhWLRo0Rdu0/LAdHZ2tvqQlKhWq5U9Ai1UrVbLHoEWuZj38pYHxm2x9tLV1VX2CECCi3kv95AfgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSTCkw27Zti5tuuinmzZsXfX198fbbb1/uuQCY5poOzIsvvhibNm2KLVu2xJEjR2L58uXxwAMPxNmzZzPmA2CaqhRFUTSzQ19fX6xYsSKee+65iIgYHx+Pnp6eeOKJJ+LnP//5l+5fr9ejWq1ObVqmnSZfXkxzlUql7BFokVqtFl1dXV+4TVNXMJ9++mkcPnw4Vq1a9d9vMGtWrFq1Kt56660L7tNoNKJer5+3ADDzNRWYTz75JMbGxmLhwoXnrV+4cGGcPn36gvsMDg5GtVqdWHp6eqY+LQDTRvpPkW3evDlqtdrEMjw8nH1IAL4C5jSz8XXXXRezZ8+OM2fOnLf+zJkzccMNN1xwn46Ojujo6Jj6hABMS01dwcydOzfuvPPO2Ldv38S68fHx2LdvX/T391/24QCYvpq6gomI2LRpU6xbty7uuuuuWLlyZTz77LMxOjoajz/+eMZ8AExTTQfmsccei48//jh+8YtfxOnTp+Nb3/pWvP7665978A9Ae2v6czCXyudg2ovPwbQXn4NpH5f9czAAcLEEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUswpe4B2UhRF2SO0XKVSKXsEWshrnP/lCgaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQIqmA3PgwIF46KGHoru7OyqVSrz88ssJYwEw3TUdmNHR0Vi+fHls27YtYx4AZog5ze6wevXqWL16dcYsAMwgTQemWY1GIxqNxsTX9Xo9+5AAfAWkP+QfHByMarU6sfT09GQfEoCvgPTAbN68OWq12sQyPDycfUgAvgLSb5F1dHRER0dH9mEA+IrxORgAUjR9BXPu3Lk4fvz4xNcnTpyIo0ePxvz582Px4sWXdTgApq9KURRFMzvs378/vv/9739u/bp162Lnzp1fun+9Xo9qtdrMIWeMJv9TzwiVSqXsEWghr/H2UavVoqur6wu3aTowl0pg2ku7/uFrV17j7eNiAuMZDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApJhT1oFrtVp0dXWVdfhSVCqVskeAVO34Gi+KouwRWqper0e1Wr2obV3BAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApGgqMIODg7FixYro7OyM66+/Ph555JF4//33s2YDYBprKjBDQ0MxMDAQBw8ejL1798Znn30W999/f4yOjmbNB8A0VSmKopjqzh9//HFcf/31MTQ0FN/97ncvap96vR7VajVqtVp0dXVN9dDTUqVSKXsE4DK7hLfQaamZ9/A5l3KgWq0WERHz58+fdJtGoxGNRuO84QCY+ab8kH98fDw2btwYd999dyxbtmzS7QYHB6NarU4sPT09Uz0kANPIlG+R/fSnP43XXnst3nzzzVi0aNGk213oCqanp8ctMmBGcItsclO6RbZhw4Z49dVX48CBA18Yl4iIjo6O6OjomMphAJjGmgpMURTxxBNPxJ49e2L//v1x8803Z80FwDTXVGAGBgZi165d8corr0RnZ2ecPn06IiKq1WpcccUVKQMCMD019QxmsmcIL7zwQvzoRz+6qO/hx5SBmcQzmMk1fYsMAC6G30UGQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASBFU4HZvn179Pb2RldXV3R1dUV/f3+89tprWbMBMI01FZhFixbF1q1b4/Dhw/HOO+/EvffeGw8//HC89957WfMBME1ViqIoLuUbzJ8/P375y1/G+vXrL2r7er0e1Wo1arVadHV1Xcqhp51KpVL2CMBldolvodNOM+/hc6Z6kLGxsfjjH/8Yo6Oj0d/fP+l2jUYjGo3GecMBMPM1/ZD/2LFjcdVVV0VHR0f85Cc/iT179sTtt98+6faDg4NRrVYnlp6enksaGIDpoelbZJ9++ml89NFHUavV4qWXXornn38+hoaGJo3Mha5genp63CIDZgS3yCZ3yc9gVq1aFV//+tdjx44dl324mUZgYOYRmMld8udgxsfHz7tCAYCIJh/yb968OVavXh2LFy+OkZGR2LVrV+zfvz/eeOONrPkAmKaaCszZs2fjhz/8YZw6dSqq1Wr09vbGG2+8ET/4wQ+y5gNgmmoqML/73e+y5gBghvG7yABIITAApBAYAFIIDAApBAaAFAIDQAqBASCFwACQQmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBiTlkHrlarZR26NEVRlD1Cy1UqlbJHoIW8xvlfrmAASCEwAKQQGABSCAwAKQQGgBQCA0AKgQEghcAAkEJgAEghMACkEBgAUggMACkEBoAUAgNACoEBIIXAAJBCYABIITAA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PBP33HNPvPvuu9HZ2Vn2eJ8z4wNDexoYGIh33333q31/+jK67bbb4ujRo1Gr1eKll16KdevWxdDQ0IyNzPDwcDz55JOxd+/emDdvXtnjtMzq1asn/rm3tzf6+vpiyZIl8Yc//CHWr19f4mQXNuMDc91118Xs2bPjzJkz560/c+ZM3HDDDSVNRaYNGzbEq6++GgcOHCj1r4Zopblz58Y3vvGNiIi4884749ChQ/HrX/86duzYUfJkOQ4fPhxnz56Nb3/72xPrxsbG4sCBA/Hcc89Fo9GI2bNnlzhha1x99dVx6623xvHjx8se5YJm/DOYuXPnxp133hn79u2bWDc+Ph779u1ri3vU7aQoitiwYUPs2bMn/vKXv8TNN99c9kilGR8fj0ajUfYYae677744duxYHD16dGK56667Yu3atXH06NG2iEtExLlz5+LDDz+MG2+8sexRLmjGX8FERGzatCnWrVsXd911V6xcuTKeffbZGB0djccff7zs0dKcO3fuvP+rOXHiRBw9ejTmz58fixcvLnGyPAMDA7Fr16545ZVXorOzM06fPh0R//+XI11xxRUlT5dn8+bNsXr16li8eHGMjIzErl27Yv/+/fHGG2+UPVqazs7Ozz1bu/LKK+Paa6+d0c/cnnrqqXjooYdiyZIlcfLkydiyZUvMnj071qxZU/ZoF1b2j7G1ym9+85ti8eLFxdy5c4uVK1cWBw8eLHukVH/961+LiPjcsm7durJHS3Oh842I4oUXXih7tFQ//vGPiyVLlhRz584tFixYUNx3333Fn/70p7LHarl2+DHlxx57rLjxxhuLuXPnFl/72teKxx57rDh+/HjZY03Kr+sHIMWMfwYDQDkEBoAUAgNACoEBIIXAAJBCYABIITAApBAYAFIIDAApBAaAFAIDQAqBASDF/wGT9/Q5JEvb6gAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import torch\n",
    "import cv2\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "x = torch.tensor([\n",
    "    [0, 0, 1, 1, 0, 0],\n",
    "    [0, 1, 0, 0, 1, 0],\n",
    "    [1, 0, 0, 0, 0, 1],\n",
    "    [1, 0, 0, 0, 0, 1],\n",
    "    [0, 1, 0, 0, 1, 0],\n",
    "    [0, 0, 1, 1, 0, 0]\n",
    "], dtype=float)\n",
    "\n",
    "plt.imshow(x, cmap='gray')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面这个卷积核用于检测反对角线，卷积核中每个元素可以视为权重，匹配×1，不匹配×（-1），最后输出是得分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "mask = torch.tensor([\n",
    "    [-1, -1, 1],\n",
    "    [-1, 1, -1],\n",
    "    [1, -1, -1]\n",
    "], dtype=float)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将该卷积核应用于原图上"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[[ 3., -1., -3., -1.],\n",
       "          [-1., -1.,  1., -3.],\n",
       "          [-3.,  1., -1., -1.],\n",
       "          [-1., -3., -1.,  3.]]]], dtype=torch.float64)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = torch.conv2d(x.unsqueeze(0).unsqueeze(0), mask.unsqueeze(0).unsqueeze(0))\n",
    "y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由y的结果发现，得分越高，意味着与模式想要找的特征相似度越高，所以特征图中像素点值的大小不再是一个具体的颜色，而是与模式的匹配度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将卷积放到神经网络中进行理解，卷积所提取的特征实际上可以视为回归问题中的输入（如：影响房价的因素，包括位置、质量等），而对这些特征进行回归，最后可以得到预测结果\n",
    "\n",
    "如下图中直观的描述了神经网络的计算过程，由原图经过卷积提取特征（鼻子、眼睛和嘴巴），得到与特征的相似度，最后对这些相似度经过若干全连接层得到输出（与人的相似度）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://zyc-learning-1309954661.cos.ap-nanjing.myqcloud.com/machine-learning-pic/image-20240810184939881.png\" alt=\"image-20240810184939881\" style=\"zoom:50%;\" />"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "torch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
